/*
 * Copyright (c) 2025 CAX Conversion Project
 */
package com.comac.ins.cax.service.impl;

import cn.hutool.core.lang.Assert;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.comac.ins.cax.domain.CaxGeometricCheck;
import com.comac.ins.cax.domain.CaxQualityChecker;
import com.comac.ins.cax.domain.CaxTopologyCheck;
import com.comac.ins.cax.domain.vo.CaxQualityCheckerVo;
import com.comac.ins.cax.mapper.CaxGeometricCheckMapper;
import com.comac.ins.cax.mapper.CaxQualityCheckerMapper;
import com.comac.ins.cax.mapper.CaxTopologyCheckMapper;
import com.comac.ins.cax.service.ICaxQualityCheckerService;
import com.comac.ins.cax.utils.ExecUtils;
import com.comac.ins.cax.utils.FileUtils;
import com.comac.ins.common.json.utils.JsonUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;

@Slf4j
@Service
@RequiredArgsConstructor
public class CaxQualityCheckerServiceImpl implements ICaxQualityCheckerService {
    private static final String POINT_CLOUD_CHECK_URL = "/data2/cax/quality_inspector";

    private static final String TOPOLOGY_CHECK_URL = "/data2/cax/quality_inspector";

    private static final String GEOMETRIC_CHECK_URL = "/data2/cax/quality_inspector";

    private static final String POINT_CLOUD_CHECK_TOOL = "./point_cloud_inspector";

    private static final String TOPOLOGY_CHECK_TOOL = "./topology_inspector";

    private static final String GEOMETRIC_CHEC_TOOL = "./geometric_inspector";


    @Autowired
    private CaxQualityCheckerMapper caxQualityCheckerMapper;

    @Autowired
    private CaxTopologyCheckMapper caxTopologyCheckMapper;

    @Autowired
    private CaxGeometricCheckMapper caxGeometricCheckMapper;

    @Override
    public void check(Long convertId, String sourceFilePath, String targetFilePath) {
        pointCloudCheck(convertId, sourceFilePath, targetFilePath);
        topologyCheck(convertId, sourceFilePath, targetFilePath);
        geometricCheck(convertId, sourceFilePath, targetFilePath);
    }

    private void pointCloudCheck(Long convertId, String sourceFilePath, String targetFilePath) {
        log.info("----->开始进行转换质量检查-点云校验<-----");
        String outputFilePath = "";
        try {
            File file = new File(sourceFilePath);
            String parentPath = file.getParent();
            Path destinationFile = Paths.get(parentPath, "pointCloudCheckResult.json");
            outputFilePath = destinationFile.toString();
            String logUrl = FileUtils.changeFileExtension(outputFilePath, "log");
            String str = "cd " + POINT_CLOUD_CHECK_URL + " && source /data2/cax/quality_inspector/.bash_env" + " && " + POINT_CLOUD_CHECK_TOOL + " -i \"" + sourceFilePath + "," + targetFilePath + "\" -o " + outputFilePath;
            log.error(str);
            String[] cmd = new String[]{"/bin/sh", "-c", str};
            ExecUtils.exec(cmd, logUrl);
        } catch (Exception e) {
            log.error("转换质量检查失败！", e);
            return;
        }
        log.info("----->转换质量检查结束-点云校验<-----");

        //解析文件,往db中储存数据
        try {
            //测试文件
            //outputFilePath ="C:\\Users\\Administrator\\Desktop\\fsdownload\\result.json";

            String jsonResult = this.parseFile(outputFilePath);

            CaxQualityChecker caxQualityChecker = new CaxQualityChecker();
            Map map = JsonUtils.parseObject(jsonResult, Map.class);
            Assert.notNull(map, "json解析异常！");
            caxQualityChecker.setExcess(ObjectUtils.isNotEmpty(map.get("excess")) ? map.get("excess").toString() : null);
            caxQualityChecker.setMissed(ObjectUtils.isNotEmpty(map.get("missed")) ? map.get("missed").toString() : null);
            caxQualityChecker.setConverged(ObjectUtils.isNotEmpty(map.get("converged")) ? map.get("converged").toString() : null);
            caxQualityChecker.setScore(ObjectUtils.isNotEmpty(map.get("score")) ? map.get("score").toString() : null);
            caxQualityChecker.setSourceTotalSize(ObjectUtils.isNotEmpty(map.get("source_total_size")) ? map.get("source_total_size").toString() : null);
            caxQualityChecker.setTargetTotalSize(ObjectUtils.isNotEmpty(map.get("target_total_size")) ? map.get("target_total_size").toString() : null);

            double missedRatio = Double.parseDouble(caxQualityChecker.getMissed()) / Double.parseDouble(caxQualityChecker.getSourceTotalSize()) * 100;
            double excessRatio = Double.parseDouble(caxQualityChecker.getExcess()) / Double.parseDouble(caxQualityChecker.getSourceTotalSize()) * 100;
            caxQualityChecker.setMissedRatio(String.format("%.2f", missedRatio));
            caxQualityChecker.setExcessRatio(String.format("%.2f", excessRatio));
            caxQualityChecker.setConvertId(convertId);
            caxQualityCheckerMapper.insert(caxQualityChecker);
        } catch (Exception e) {
            log.error("保存质量检测-点云校验结果失败！", e);
            return;
        }
    }

    private void topologyCheck(Long convertId, String sourceFilePath, String targetFilePath) {
        log.info("----->开始进行转换质量检查-拓扑校验<-----");
        String outputFilePath1 = "";
        String outputFilePath2 = "";
        try {
            File file = new File(sourceFilePath);
            String parentPath = file.getParent();
            Path destinationFile1 = Paths.get(parentPath, "topologyCheckResult1.json");
            Path destinationFile2 = Paths.get(parentPath, "topologyCheckResult2.json");
            outputFilePath1 = destinationFile1.toString();
            outputFilePath2 = destinationFile2.toString();
            // 执行两次，源文件
            String logUrl1 = FileUtils.changeFileExtension(outputFilePath1, "log");
            String str1 = "cd " + TOPOLOGY_CHECK_URL + " && source /data2/cax/quality_inspector/.bash_env" + " && " + TOPOLOGY_CHECK_TOOL + " -i \"" + sourceFilePath + "\" -o " + outputFilePath1;
            log.error(str1);
            String[] cmd1 = new String[]{"/bin/sh", "-c", str1};
            ExecUtils.exec(cmd1, logUrl1);
            // 执行两次，转换文件
            String logUrl2 = FileUtils.changeFileExtension(outputFilePath2, "log");
            String str2 = "cd " + TOPOLOGY_CHECK_URL + " && source /data2/cax/quality_inspector/.bash_env" + " && " + TOPOLOGY_CHECK_TOOL + " -i \"" + targetFilePath + "\" -o " + outputFilePath2;
            log.error(str2);
            String[] cmd2 = new String[]{"/bin/sh", "-c", str2};
            ExecUtils.exec(cmd2, logUrl2);
        } catch (Exception e) {
            log.error("转换质量拓扑校验检查失败！", e);
        }
        log.info("----->转换质量检查结束-拓扑校验<-----");
        //解析文件,往db中储存数据
        try {
            //测试文件
            CaxTopologyCheck caxTopologyCheck = new CaxTopologyCheck();
            caxTopologyCheck.setTargetFilePath(outputFilePath1 + "," + outputFilePath2);
            caxTopologyCheck.setConvertId(convertId);
            caxTopologyCheckMapper.insert(caxTopologyCheck);
        } catch (Exception e) {
            log.error("保存质量检测拓扑校验<结果失败！", e);
        }
    }

    private void geometricCheck(Long convertId, String sourceFilePath, String targetFilePath) {
        log.info("----->开始进行转换质量检查-几何校验<-----");
        String outputFilePath = "";
        try {
            File file = new File(sourceFilePath);
            String parentPath = file.getParent();
            Path destinationFile = Paths.get(parentPath, "geometricCheckResult.json");
            outputFilePath = destinationFile.toString();
            String logUrl = FileUtils.changeFileExtension(outputFilePath, "log");
            String str = "cd " + GEOMETRIC_CHECK_URL + " && source /data2/cax/quality_inspector/.bash_env" + " && " + GEOMETRIC_CHEC_TOOL + " -i \"" + sourceFilePath + "," + targetFilePath + "\" -o " + outputFilePath;
            log.error(str);
            String[] cmd = new String[]{"/bin/sh", "-c", str};
            ExecUtils.exec(cmd, logUrl);
        } catch (Exception e) {
            log.error("转换质量几何校验检查失败！", e);
            return;
        }
        log.info("----->转换质量检查结束-几何校验<-----");

        //解析文件,往db中储存数据
        try {
            //测试文件
            //outputFilePath ="C:\\Users\\Administrator\\Desktop\\fsdownload\\result.json";

            String jsonResult = this.parseFile(outputFilePath);

            CaxGeometricCheck caxGeometricCheck = new CaxGeometricCheck();
            Map map = JsonUtils.parseObject(jsonResult, Map.class);
            Assert.notNull(map, "json解析异常！");
            caxGeometricCheck.setDestSurfaceArea(ObjectUtils.isNotEmpty(map.get("dest_surface_area")) ? map.get("dest_surface_area").toString() : null);
            caxGeometricCheck.setDestVertexCount(ObjectUtils.isNotEmpty(map.get("dest_vertex_count")) ? map.get("dest_vertex_count").toString() : null);
            caxGeometricCheck.setConverged(ObjectUtils.isNotEmpty(map.get("converged")) ? map.get("converged").toString() : null);
            caxGeometricCheck.setScore(ObjectUtils.isNotEmpty(map.get("score")) ? map.get("score").toString() : null);
            caxGeometricCheck.setDestVolumn(ObjectUtils.isNotEmpty(map.get("dest_volume")) ? map.get("dest_volume").toString() : null);
            caxGeometricCheck.setSrcSurfaceArea(ObjectUtils.isNotEmpty(map.get("src_surface_area")) ? map.get("src_surface_area").toString() : null);
            caxGeometricCheck.setSrcVertexCount(ObjectUtils.isNotEmpty(map.get("src_vertex_count")) ? map.get("src_vertex_count").toString() : null);
            caxGeometricCheck.setSrcVolumn(ObjectUtils.isNotEmpty(map.get("src_volume")) ? map.get("src_volume").toString() : null);
            caxGeometricCheck.setConvertId(convertId);
            caxGeometricCheckMapper.insert(caxGeometricCheck);
        } catch (Exception e) {
            log.error("保存质量检测几何校验结果失败！", e);
            return;
        }
    }

    @Override
    public CaxQualityCheckerVo queryByConvertId(Long convertId) {
        return caxQualityCheckerMapper.selectVoOne(new LambdaQueryWrapper<CaxQualityChecker>().eq(CaxQualityChecker::getConvertId, convertId));
    }

    /**
     * 解析文件
     *
     * @return
     */
    public String parseFile(String filePath) throws IOException {
        // 读取所有行到List<String>
        List<String> allLines = Files.readAllLines(Paths.get(filePath));
        // 将List<String>转换为单个字符串
        String content = String.join(System.lineSeparator(), allLines);
        return content;
    }
}
